#include "loginwidget.h"
#include "mainwidget.h"
#include "toast.h"
#include "verifycodewidget.h"
#include "model/datacenter.h"


#include <QGridLayout>
#include <QGuiApplication>
#include <QScreen>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>

LoginWidget::LoginWidget(QWidget* parent)
    : QWidget(parent), isLoginMode(true), isAccountLogin(true)
{
    // 1.设置窗口基本属性
    this->setFixedSize(400, 350);
    this->setWindowTitle("登录");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    this->setStyleSheet("QWidget { background-color: rgb(255, 255, 255); }");
    this->setAttribute(Qt::WA_DeleteOnClose);

    // 2.网格布局
    layout = new QGridLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(50, 0, 50, 0);
    this->setLayout(layout);

    // 2-2 初始化登录窗口
    initAccountLoginWidget();
    initPhoneLoginWidget();

    // 2-3 默认账号登录
    switchAccountLoginWidget();

    // 3.切换按钮信号槽
    connect(switchLoginModeBtn, &QPushButton::clicked, this, [=](){
        if(isAccountLogin) {
            switchPhoneLoginWidget();
        } else {
            switchAccountLoginWidget();
        }
        isAccountLogin = !isAccountLogin;
    });
    connect(switchWidgetModeBtn, &QPushButton::clicked, this, [=](){
        if(isLoginMode) {
            swithRegisterMode();
        } else {
            switchLoginMode();
        }
        isLoginMode = !isLoginMode;
    });

    connect(submitBtn, &QPushButton::clicked, this, &LoginWidget::onClickedBySubmitBtn, Qt::UniqueConnection);

    connect(sendVerifyCodeBtn, &QPushButton::clicked, this, &LoginWidget::onClickedBySendVerifyCodeBtn, Qt::UniqueConnection);
}

void LoginWidget::initAccountLoginWidget()
{
    // 1 登录标签
    titleLabel = new QLabel("登录");
    titleLabel->setAlignment(Qt::AlignCenter);
    titleLabel->setFixedHeight(50);
    titleLabel->setStyleSheet("QLabel { font-size: 36px; font-weight: 600; }");

    // 2 用户名 密码 验证码输入框
    usernameEdit = createLineEdit("输入用户名");
    passwordEdit = createLineEdit("输入密码");
    passwordConfirmEdit = createLineEdit("密码确认");
    passwordEdit->setEchoMode(QLineEdit::Password);
    passwordConfirmEdit->setEchoMode(QLineEdit::Password);
    verifyCodeEdit = createLineEdit("输入验证码");

    // 3 验证码按钮(TODO: 生成验证码图片)
    verifyCodeWidget = new VerifyCodeWidget(this);
    verifyCodeWidget->setStyleSheet("QPushButton { border: none; }");

    // 4 登录按钮
    submitBtn = new QPushButton("登录");
    submitBtn->setFixedHeight(40);
    submitBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    submitBtn->setStyleSheet(getSubmitBtnStyle());

    // 5.切换手机号登录按钮/注册按钮
    switchLoginModeBtn = new QPushButton("手机号登录");
    switchLoginModeBtn->setFixedSize(100, 40);
    switchLoginModeBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    switchLoginModeBtn->setStyleSheet(getSwitchBtnStyle());

    switchWidgetModeBtn = new QPushButton("注册");
    switchWidgetModeBtn->setFixedSize(100, 40);
    switchWidgetModeBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    switchWidgetModeBtn->setStyleSheet(getSwitchBtnStyle());
}

void LoginWidget::initPhoneLoginWidget()
{
    // 1.手机号码输入框
    phoneEdit = createLineEdit("输入手机号");

    // 2.短信输入框(不需要变动)

    // 3.发送短信按钮
    sendVerifyCodeBtn = new QPushButton("发送验证码");
    sendVerifyCodeBtn->setFixedSize(100, 40);
    sendVerifyCodeBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    sendVerifyCodeBtn->setStyleSheet(getSwitchBtnStyle());

    // 4.提交按钮(不需要变动)

    // 5.切换登录模式
    switchLoginModeBtn->setText("账号登录");

    // 6.切换窗口模式(不需要变动)
}

void LoginWidget::switchAccountLoginWidget()
{
    // 1.移除原本的控件布局
    clearLayout();

    // 2.添加该登录模式的控件
    layout->addWidget(titleLabel, 0, 0, 1, 5);
    layout->addWidget(usernameEdit, 1, 0, 1, 5);
    layout->addWidget(passwordEdit, 2, 0, 1, 5);
    layout->addWidget(verifyCodeEdit, 3, 0, 1, 4);
    layout->addWidget(verifyCodeWidget, 3, 4, 1, 1);
    layout->addWidget(submitBtn, 4, 0, 1, 5);
    layout->addWidget(switchLoginModeBtn, 5, 0, 1, 1);
    layout->addWidget(switchWidgetModeBtn, 5, 4, 1, 1);

    titleLabel->show();
    usernameEdit->show();
    passwordEdit->show();
    verifyCodeEdit->show();
    verifyCodeWidget->show();
    submitBtn->show();
    switchLoginModeBtn->show();
    switchWidgetModeBtn->show();

    // 登录模式下触发的切换账号登录, 即当前是手机登录, 那么切换后为账号登录，就应该显示手机登录
    // 注册模式下调用的切换账号登录, 即注册前的状态是账号登录, 还原为注册前的状态
    // 综上, 两张情况都是手机登录
    switchLoginModeBtn->setText("手机号登录");

    this->claerLineEdit();
}

void LoginWidget::switchPhoneLoginWidget()
{
    // 1.移除原本的控件布局
    clearLayout();

    // 2.添加该登录模式的控件
    layout->addWidget(titleLabel, 0, 0, 1, 5);
    layout->addWidget(phoneEdit, 1, 0, 1, 5);
    layout->addWidget(verifyCodeEdit, 2, 0, 1, 4);
    layout->addWidget(sendVerifyCodeBtn, 2, 4, 1, 1);
    layout->addWidget(submitBtn, 3, 0, 1, 5);
    layout->addWidget(switchLoginModeBtn, 4, 0, 1, 1);
    layout->addWidget(switchWidgetModeBtn, 4, 4, 1, 1);

    titleLabel->show();
    phoneEdit->show();
    verifyCodeEdit->show();
    submitBtn->show();
    sendVerifyCodeBtn->show();
    switchLoginModeBtn->show();
    switchWidgetModeBtn->show();

    // 登录模式下触发的切换手机登录, 即当前是账号登录, 那么切换后为手机登录，就应该显示账号登录
    // 注册模式下调用的切换手机登录, 即注册前的状态是手机登录, 就应该显示账号登录
    // 综上, 两张情况都是账号登录
    switchLoginModeBtn->setText("账号登录");

    this->claerLineEdit();
}

void LoginWidget::switchLoginMode()
{
    this->setWindowTitle("登录");
    titleLabel->setText("登录");
    submitBtn->setText("登录");
    isAccountLogin ? switchLoginModeBtn->setText("手机号登录") : switchLoginModeBtn->setText("账号登录");
    switchWidgetModeBtn->setText("注册");

    this->clearLayout();

    this->setFixedSize(400, 350);
    this->move(this->pos().x(), this->pos().y() + 50);

    utils::TimeUtil::buttonCountDownStop(sendVerifyCodeBtn);

    isAccountLogin ? this->switchAccountLoginWidget() : this->switchPhoneLoginWidget();

    this->claerLineEdit();
}

void LoginWidget::swithRegisterMode()
{
    this->setWindowTitle("注册");
    titleLabel->setText("注册");
    submitBtn->setText("注册");
    switchLoginModeBtn->hide();
    switchWidgetModeBtn->setText("登录");

    this->clearLayout();

    this->setFixedSize(400, 450);
    this->move(this->pos().x(), this->pos().y() - 50);

    utils::TimeUtil::buttonCountDownStop(sendVerifyCodeBtn);

    layout->addWidget(titleLabel, 0, 0, 1, 5);
    layout->addWidget(usernameEdit, 1, 0, 1, 5);
    layout->addWidget(passwordEdit, 2, 0, 1, 5);
    layout->addWidget(passwordConfirmEdit, 3, 0, 1, 5);
    layout->addWidget(phoneEdit, 4, 0, 1, 5);
    layout->addWidget(verifyCodeEdit, 5, 0, 1, 4);
    layout->addWidget(sendVerifyCodeBtn, 5, 4, 1, 1);
    layout->addWidget(submitBtn, 6, 0, 1, 5);
    layout->addWidget(switchWidgetModeBtn, 7, 4, 1, 1);

    titleLabel->show();
    usernameEdit->show();
    passwordEdit->show();
    passwordConfirmEdit->show();
    phoneEdit->show();
    verifyCodeEdit->show();
    sendVerifyCodeBtn->show();
    submitBtn->show();
    switchWidgetModeBtn->show();

    this->claerLineEdit();
}


void LoginWidget::clearLayout()
{
    // 保留标题
    for(int i = layout->count() - 1; i >= 0; --i) {
        layout->takeAt(i)->widget()->hide();
    }
}

void LoginWidget::claerLineEdit()
{
    usernameEdit->clear();
    passwordEdit->clear();
    passwordConfirmEdit->clear();
    phoneEdit->clear();
    verifyCodeEdit->clear();
}

void LoginWidget::onClickedBySubmitBtn()
{
    const QString& username = usernameEdit->text();
    const QString& password = passwordEdit->text();
    const QString& passwordConfirm = passwordConfirmEdit->text();
    const QString& verifyCode = verifyCodeEdit->text();
    const QString& phone = phoneEdit->text();

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(isLoginMode)
    {
        connect(dataCenter, &model::DataCenter::loginDone, this, &LoginWidget::loginDoneHandle);
        if(isAccountLogin)
        {
            if(username.isEmpty() || password.isEmpty() || verifyCode.isEmpty()) {
                Toast::showMessage("用户名/密码/验证码不能为空!");
                return;
            }
            if(!verifyCodeWidget->checkVerifyCode(verifyCode)) {
                Toast::showMessage("验证码错误");
                verifyCodeWidget->refreshVerifyCode();
                return;
            }
            dataCenter->AccountLoginAsync(username, password);
        } else {
            if(phone.isEmpty() || verifyCode.isEmpty()) {
                Toast::showMessage("用户名/密码/验证码不能为空!");
                return;
            }
            if(phone.compare(currentPhone) != 0) {
                Toast::showMessage("验证码错误, 当前验证码不属于该手机号");
                return;
            }
            dataCenter->phoneLoginAsync(phone, verifyCode);
        }
    }
    else
    {
        if(username.isEmpty() || password.isEmpty() || passwordConfirm.isEmpty() || phone.isEmpty() || verifyCode.isEmpty()) {
            Toast::showMessage("用户名/密码/手机号/验证码不能为空!");
            return;
        }
        if(password.compare(passwordConfirm) != 0) {
            Toast::showMessage("密码不一致, 请重新输入!");
            return;
        }
        if(phone.compare(currentPhone) != 0) {
            Toast::showMessage("验证码错误, 当前验证码不属于该手机号");
            return;
        }
        connect(dataCenter, &model::DataCenter::userRegisterDone, this, &LoginWidget::registerDoneHandle);
        dataCenter->userRegisterAsync(username, password, phone, verifyCode);
    }
}

void LoginWidget::onClickedBySendVerifyCodeBtn()
{
    const QString& phone = phoneEdit->text();
    const QString& password = passwordEdit->text();
    const QString& passwordConfirm = passwordConfirmEdit->text();
    if(password.compare(passwordConfirm) != 0) {
        Toast::showMessage("密码不一致, 请重新输入!");
        return;
    }
    if(phone.isEmpty()) {
        Toast::showMessage("手机号为空, 无法获取验证码");
        return;
    }

    this->currentPhone = phone;

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::getVerifyCodeDone, this, &LoginWidget::getVerifyCodeDoneHandle);
    dataCenter->getVerifyCodeAsync(phone);

    utils::TimeUtil::buttonEnableCountDown(countdownTimer, this, sendVerifyCodeBtn, 30, 1000, true);
    sendVerifyCodeBtn->setEnabled(false);
}

void LoginWidget::loginDoneHandle(bool ok, const QString &reason)
{
    if(!ok) {
        Toast::showMessage("登录失败, " + reason);
        return;
    }

    MainWidget* mainWidget = MainWidget::getInstance();
    mainWidget->show();

    this->close();
}

void LoginWidget::registerDoneHandle(bool ok, const QString &reason)
{
    if(!ok) {
        Toast::showMessage("注册失败, " + reason);
        return;
    }

    this->switchLoginMode();
    isLoginMode = !isLoginMode;
    phoneEdit->clear();
    verifyCodeEdit->clear();
    utils::TimeUtil::buttonCountDownStop(sendVerifyCodeBtn);
}

void LoginWidget::getVerifyCodeDoneHandle()
{
    Toast::showMessage("验证码已发送");
}


QLineEdit* LoginWidget::createLineEdit(const QString& text)
{
    QLineEdit* labelEdit = new QLineEdit();
    labelEdit->setPlaceholderText(text);
    labelEdit->setFixedHeight(40);
    labelEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    labelEdit->setStyleSheet("QLineEdit { border: none; border-radius: 5px; font-size: 14px; padding-left: 7px; "
                             "background-color: rgb(240, 240, 240); }");
    return labelEdit;
}

QString LoginWidget::getSwitchBtnStyle()
{
    static QString switchBtnStyle = "QPushButton { border: none; border-radius: 5px; } "
                                    "QPushButton:pressed { background-color: rgb(240, 240, 235); }";
    return switchBtnStyle;
}

QString LoginWidget::getSubmitBtnStyle()
{
    static QString submitBtnStyle = "QPushButton { border: none; border-radius: 10px; "
                                    "background-color: rgb(44, 182, 61); color: white; font: 16px; }"
                                    "QPushButton:pressed { background-color: rgb(240, 240, 240); }";
    return submitBtnStyle;
}

